﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web.Mvc;
using Newtonsoft.Json;

namespace Ext.Direct.Mvc
{
    public class DirectController : Controller
    {
        private object[] _data;
        private DirectRequest _directRequest;

        public object[] Data {
            get {
                if (_data == null) {
                    _data = this.DirectRequest == null ? null : this.DirectRequest.Data;
                }
                return _data;
            }
        }

        public DirectRequest DirectRequest {
            get {
                if (_directRequest == null) {
                    _directRequest = HttpContext.Items[DirectRequest.DirectRequestKey] as DirectRequest;
                }
                return _directRequest;
            }
        }

        protected override void ExecuteCore() {
            if (ControllerContext.RouteData.RouteHandler is DirectMvcRouteHandler) {
                this.ActionInvoker = new DirectMethodInvoker();
            } else if (IsDirectMethodCall()) {
                throw new InvalidOperationException("This controller action can only be executed by Ext.Direct.");
            }
            base.ExecuteCore();
        }

        protected internal DirectResult Direct(object data) {
            return Direct(data, null);
        }

        protected internal DirectResult Direct(object data, IList<JsonConverter> converters) {
            return Direct(data, converters, null);
        }

        protected internal DirectResult Direct(object data, IList<JsonConverter> converters, JsonSerializerSettings settings) {
            return Direct(data, converters, settings, null);
        }

        protected internal DirectResult Direct(object data, IList<JsonConverter> converters, JsonSerializerSettings settings, string contentType) {
            return Direct(data, converters, settings, contentType, null);
        }

        protected internal virtual DirectResult Direct(object data, IList<JsonConverter> converters, JsonSerializerSettings settings, string contentType, Encoding contentEncoding) {
            return new DirectResult {
                Data = data,
                Converters = converters,
                Settings = settings,
                ContentType = contentType,
                ContentEncoding = contentEncoding
            };
        }

        private bool IsDirectMethodCall() {
            string controller = ControllerContext.RouteData.GetRequiredString("controller");
            string action = ControllerContext.RouteData.GetRequiredString("action");
            DirectProvider provider = DirectProvider.GetCurrentProvider();
            if (provider.GetActionMethod(controller, action) != null) {
                return true;
            }
            return false;
        }
    }
}